/*
 * File:   Mutex_Wrapper.h
 * Author: ranjeet
 *
 *Wraps posix mutex in a class
 *
 * Created on January 1, 2009, 2:28 PM
 */

#ifndef _MUTEX_WRAPPER_H
#define	_MUTEX_WRAPPER_H

#include <iostream>
#include <string.h>
#include <stdexcept>
#include <pthread.h>
#include "Utils.h"
#include "Debug.h"


using namespace std;


///a simple class to wrap posix mutex
class Mutex_Wrapper {
public:

    /**
     *\brief constructor
     *
     *By default (bool _throwexception = true) functions throw exception
     *Calls pthread_mutexattr_init to set attribute to blank
     *Calls pthread_mutexattr_settype to set PTHREAD_MUTEX_RECURSIVE
     *Initialize mutex by calling pthread_mutex_init
     *Initilizes tid to -1
     */
    Mutex_Wrapper(bool _throwexception = true) throw(runtime_error);

    /**
     * \brief destructor
     *
     *Calls pthread_mutex_destroy to destory the mutex
     */
   ~Mutex_Wrapper();

   /**
    *\brief locks the mutex
    *
    *Calls pthread_mutex_lock() the mutex
    *Initialize the variable tid to the id of (current) thread that locks
    */
   void lock()    throw(runtime_error);

   /**
    *\brief unlocks the mutex
    *
    *Calls pthread_mutex_unlock to unlock the mutex
    */
   void unlock()  throw(runtime_error);

   /**
    *\brief tries to lock the mutex
    *
    *Calls pthread_mutex_trylock to try to lock mutex
    *If mutex is already locked it throws exception
    */
    void try_lock() throw(runtime_error);

    ///Returns id of thread locking the mutex
    pthread_t getCurrent(void) const;

    ///Returns reference to mutex
    pthread_mutex_t& getMutex();

private:

    ///If true function throw on error
    bool            throw_exception;

    ///The wrapped mutex
    pthread_mutex_t mutex;

    ///Keeps id of thread locking the mutex
    pthread_t       tid;

};


#endif	/* _MUTEX_WRAPPER_H */

